package com.helin.helinhealth.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.helin.helinhealth.common.Result;

import com.helin.helinhealth.entity.Medicine;
import com.helin.helinhealth.service.MedicineService;
import com.helin.helinhealth.utils.UserContext;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 药品控制器
 * 
 * <p>
 * 该控制器处理与药品管理相关的HTTP请求，包括药品的增删改查、服药打卡、库存管理等功能。
 * 提供RESTful风格的API接口，主要供老人端和子女端小程序调用。
 * </p>
 * 
 * <p>
 * 主要功能包括：
 * - 药品信息的添加和更新
 * - 药品列表查询（支持分页和条件筛选）
 * - 服药打卡功能
 * - 库存管理和预警
 * - 今日待服用药品提醒
 * </p>
 * 
 * <p>
 * 所有接口都通过{@link Result}包装返回结果，统一了响应格式，
 * 并加入了异常处理机制，确保前端能收到明确的错误提示。
 * </p>
 */
@Tag(name = "用药管理", description = "用药管理相关接口")
@RestController
@RequestMapping("/api/medicine")
public class MedicineController {

    /**
     * 药品服务，用于处理药品相关的业务逻辑
     */
    @Autowired
    private MedicineService medicineService;

    /**
     * 添加或更新药品
     * 
     * <p>
     * 处理药品的新增和更新请求，根据药品ID是否存在自动判断操作类型。
     * 新增药品时会自动关联当前登录用户，更新时会验证用户权限。
     * </p>
     * 
     * @param medicine 药品信息对象，从请求体中获取
     * @return 操作结果
     */
    @Operation(summary = "添加或更新药品", description = "添加或更新药品")
    @PostMapping("/saveOrUpdate")
    public Result addOrupdateMedicine(@RequestBody Medicine medicine) {
        try {
            medicineService.saveOrupdate(medicine);
            return Result.success("操作成功");
        } catch (Exception e) {
            return Result.error("操作失败: " + e.getMessage());
        }
    }

    /**
     * 根据id删除药品
     * 
     * <p>
     * 根据ID删除指定药品，会进行权限验证，确保用户只能删除自己的药品。
     * 实际是逻辑删除，将is_deleted字段设为1，而非物理删除数据。
     * </p>
     * 
     * @param id 要删除的药品ID
     * @return 操作结果
     */
    @Operation(summary = "根据id删除药品", description = "根据id删除药品")
    @PostMapping("/removeById")
    public Result removeMedicineById(@RequestParam Long id) {
        try {
            // 验证是否是当前用户的药品
            String currentUserOpenid = UserContext.getCurrentUserOpenid();
            Medicine medicine = medicineService.getById(id);
            
            if (medicine == null) {
                return Result.error("药品不存在");
            }
            
            if (!currentUserOpenid.equals(medicine.getUserId())) {
                return Result.error("无权操作此药品");
            }
            
            boolean success = medicineService.removeById(id);
            return success ? Result.success("删除成功") : Result.error("删除失败");
        } catch (Exception e) {
            return Result.error("删除失败: " + e.getMessage());
        }
    }

    /**
     * 获取药品详情
     * 
     * <p>
     * 根据ID查询药品的详细信息，会进行权限验证。
     * 子女角色可以查看关联老人的药品信息，实现远程监控功能。
     * </p>
     * 
     * @param id 药品ID
     * @return 药品详细信息
     */
    @Operation(summary = "根据ID获取药品详细信息")
    @GetMapping("/getDetailById")
    public Result getDetailById(@RequestParam Long id) {
        try {
            Medicine medicine = medicineService.getById(id);
            if (medicine == null) {
                return Result.error("药品不存在");
            }
            
            // 验证是否是当前用户的药品
            String currentUserOpenid = UserContext.getCurrentUserOpenid();
            if (!currentUserOpenid.equals(medicine.getUserId())) {
                // 如果是子女角色，检查是否与老人有关联关系
                if (UserContext.isChildren()) {
                    // TODO: 子女查看老人药品的权限验证
                    // 这里暂时简化处理，实际需要通过FamilyRelationService验证关系
                } else {
                    return Result.error("无权查看此药品");
                }
            }
            
            return Result.success("获取药品详情成功", medicine);
        } catch (Exception e) {
            return Result.error("获取失败: " + e.getMessage());
        }
    }

    /**
     * 更新药品服用状态
     * 
     * <p>
     * 更新指定药品的服用状态，用于手动调整药品的服用记录。
     * 主要用于管理界面，而非服药打卡功能。
     * </p>
     * 
     * @param id 药品ID
     * @param isTaken 是否已服用
     * @return 操作结果
     */
    @Operation(summary = "更新药品服用状态")
    @PostMapping("/updateTakenStatus")
    public Result updateTakenStatus(@RequestParam Long id, @RequestParam Boolean isTaken) {
        try {
            boolean success = medicineService.updateMedicineTakenStatus(id, isTaken);
            return success ? Result.success("状态更新成功") : Result.error("状态更新失败");
        } catch (Exception e) {
            return Result.error("状态更新失败: " + e.getMessage());
        }
    }

    /**
     * 分页查询药品列表
     * 
     * <p>
     * 根据条件分页查询当前用户的药品列表，支持按药品名称模糊搜索。
     * 用于药品管理页面的列表展示，支持分页加载。
     * </p>
     * 
     * @param current 当前页码，默认1
     * @param size 每页大小，默认10
     * @param name 药品名称（可选，用于模糊搜索）
     * @return 分页结果
     */
    @Operation(summary = "分页查询药品列表")
    @GetMapping("/pageItem")
    public Result pageItem(
            @RequestParam(required = false, defaultValue = "1") Integer current,
            @RequestParam(required = false, defaultValue = "10") Integer size,
            @RequestParam(required = false) String name) {
        try {
            Page<Medicine> page = new Page<>(current, size);
            LambdaQueryWrapper<Medicine> queryWrapper = new LambdaQueryWrapper<>();
            
            // 获取当前用户ID
            String currentUserOpenid = UserContext.getCurrentUserOpenid();
            queryWrapper.eq(Medicine::getUserId, currentUserOpenid);
            
            // 如果有药品名称搜索条件
            if (name != null && !name.trim().isEmpty()) {
                queryWrapper.like(Medicine::getName, name.trim());
            }
            
            // 按创建时间降序排序
            queryWrapper.orderByDesc(Medicine::getCreateTime);
            
            IPage<Medicine> result = medicineService.page(page, queryWrapper);
            return Result.success("查询药品列表成功", result);
        } catch (Exception e) {
            return Result.error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 获取药品列表
     * 
     * <p>
     * 获取当前用户的所有药品列表，不分页，用于下拉选择等简单场景。
     * 返回的药品按创建时间降序排序。
     * </p>
     * 
     * @return 药品列表
     */
    @Operation(summary = "获取药品列表", description = "获取用户的药品列表，可筛选日期范围")
    @GetMapping("/list")
    public Result getMedicines() {
        try {
            String currentUserOpenid = UserContext.getCurrentUserOpenid();
            if (currentUserOpenid == null) {
                return Result.error("用户未登录或身份验证失败");
            }
            List<Medicine> medicines = medicineService.getUserMedicineList(currentUserOpenid);
            return Result.success("获取药品列表成功", medicines);
        } catch (Exception e) {
            e.printStackTrace(); // 打印详细堆栈信息到控制台
            return Result.error("获取失败: " + e.getMessage() + ", 原因: " + (e.getCause() != null ? e.getCause().getMessage() : "未知"));
        }
    }

    /**
     * 服药打卡
     * 
     * <p>
     * 记录用户已服用指定药品，更新药品的服用状态。
     * 是实现服药提醒和记录功能的关键接口。
     * </p>
     * 
     * @param id 药品ID
     * @return 操作结果
     */
    @Operation(summary = "服药打卡", description = "记录用户已服用药品")
    @PostMapping("/take")
    public Result takeMedicine(@RequestParam Long id) {
        try {
            boolean success = medicineService.updateMedicineTakenStatus(id, true);
            return success ? Result.success("服药打卡成功") : Result.error("服药打卡失败");
        } catch (Exception e) {
            return Result.error("服药打卡失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取今日待服用药品
     * 
     * <p>
     * 获取当前用户今日尚未服用的药品列表，按服药时间升序排序。
     * 用于首页展示服药提醒，帮助老人按时服药。
     * </p>
     * 
     * @return 今日待服用的药品列表
     */
    @Operation(summary = "获取今日待服用药品")
    @GetMapping("/today")
    public Result getTodayMedicines() {
        try {
            List<Medicine> todayMedicines = medicineService.getCurrentUserTodayMedicines();
            return Result.success("获取今日待服用药品成功", todayMedicines);
        } catch (Exception e) {
            return Result.error("获取失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取药品库存状态
     * 
     * <p>
     * 获取当前用户药品的库存状态，分为紧急（3天及以下）和预警（7天及以下）两个级别。
     * 用于库存预警功能，提醒用户及时补充药品。
     * </p>
     * 
     * @return 包含不同预警级别药品列表的结果
     */
    @Operation(summary = "获取药品库存状态")
    @GetMapping("/stockStatus")
    public Result getStockStatus() {
        try {
            // 获取不同库存阈值的药品
            List<Medicine> critical = medicineService.getLowStockMedicines(3); // 库存紧张（3天及以下）
            List<Medicine> warning = medicineService.getLowStockMedicines(7); // 库存预警（7天及以下）
            
            Map<String, Object> result = new HashMap<>();
            result.put("critical", critical);
            result.put("warning", warning);
            
            return Result.success("获取药品库存状态成功", result);
        } catch (Exception e) {
            return Result.error("获取失败: " + e.getMessage());
        }
    }
    
    /**
     * 减少药品库存天数
     * 
     * <p>
     * 减少指定药品的库存天数，用于记录用户服药后的库存变化。
     * 通常在服药打卡后自动调用，也可以手动调整库存。
     * </p>
     * 
     * @param id 药品ID
     * @param days 减少的天数，默认为1
     * @return 操作结果
     */
    @Operation(summary = "减少药品库存天数")
    @PostMapping("/reduceStock")
    public Result reduceStockDays(@RequestParam Long id, @RequestParam(defaultValue = "1") Integer days) {
        try {
            boolean success = medicineService.reduceStockDays(id, days);
            return success ? Result.success("库存更新成功") : Result.error("库存更新失败");
        } catch (Exception e) {
            return Result.error("库存更新失败: " + e.getMessage());
        }
    }
} 